package net.yc.web.imalachat.push.service;

import com.google.common.base.Strings;
import net.yc.web.imalachat.push.bean.api.account.AccountRspModel;
import net.yc.web.imalachat.push.bean.api.base.ResponseModel;
import net.yc.web.imalachat.push.bean.api.user.UpdateInfoModel;
import net.yc.web.imalachat.push.bean.card.UserCard;
import net.yc.web.imalachat.push.bean.db.User;
import net.yc.web.imalachat.push.factory.UserFactory;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: lyc
 * @data: 2021-12-31  13:34
 * @Description: 用户处理信息的Service
 */
// 172.0.0.1:8080/ImAlaChat/api/...

@Path("/user")
public class UserService extends BaseService{

    /**
     * 用户信息修改接口
     * 返回自己的个人信息
     * @param token
     * @param model
     * @return
     */
    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseModel<UserCard> update(@HeaderParam("token") String token, UpdateInfoModel model) {
        if (!UpdateInfoModel.check(model)) {
            return ResponseModel.buildParameterError();
        }

        User self = getSelf();
        // 更新用户信息
        self = model.updateToUser(self);
        self = UserFactory.update(self);
        // 架构自己的用户信息
        UserCard usercard = new UserCard(self, true);
        // 返回
        return ResponseModel.buildOk(usercard);
    }

    /**
     * 拉取联系人
     * @return
     */
    @GET
    @Path("/contact")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseModel<List<UserCard>> contact() {
        User self = getSelf();
        // 拿到我的联系人
        List<User> contacts = UserFactory.contacts(self);
        // 转换成UserCard的类型输出
        List<UserCard> userCards = contacts.stream()
                .map(user -> new UserCard(user, true))
                .collect(Collectors.toList());
        // 返回一个获取成功的标志
        return ResponseModel.buildOk(userCards);
    }

    /**
     * 关注别人，关注人的操作其实是双方同时关注
     * 修改关系使用PUT
     * @param followId
     * @return
     */
    @PUT
    @Path("/follow/{followId}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseModel<UserCard> follow(@PathParam("followId")String followId) {
        User self = getSelf();

        // 自己不能关注自己，所以如果传进去的followId和self Id一致的话，直接返回
        if (self.getId().equalsIgnoreCase(followId)
                    || Strings.isNullOrEmpty(followId)) {
            return ResponseModel.buildParameterError();
        }
        // 找到我要关注的人
        User followUser = UserFactory.findById(followId);
        if (followUser == null) {
            return ResponseModel.buildNotFoundUserError(null);
        }

        // 找到了，关注她/他
        followUser = UserFactory.follow(self, followUser, null);

        if (followUser == null) {
            // 关注失败，返回服务器异常
            return ResponseModel.buildServiceError();
        }
        // TODO 通知我关注的人我关注了他

        // 返回关注人的信息
        return ResponseModel.buildOk(new UserCard(followUser, true));
    }

    /**
     * 获取某人的信息。是否已经关注的信息也获取出来
     * @param id
     * @return
     */
    @GET
    @Path("{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseModel<UserCard> getUser (@PathParam("id") String id) {
        if (Strings.isNullOrEmpty(id)) {
            return ResponseModel.buildParameterError();
        }

        User self = getSelf();
        if (self.getId().equalsIgnoreCase(id)) {
            // 如果说查找的人是自己，则不急查询数据库，直接返回我自己
            // 默认自己是关注自己的
            return ResponseModel.buildOk(new UserCard(self, true));
        }

        User user = UserFactory.findById(id);
        if (user == null) {
            // 返回没找到用户
            return ResponseModel.buildNotFoundUserError(null);
        }

        // 如果说有关注记录，说明我已经关注了该用户
        boolean isFollow = UserFactory.getUserFollow(self, user) != null;
        return ResponseModel.buildOk(new UserCard(user, isFollow));
    }

    /**
     * 搜索人的接口实现
     * 搜索人也不涉及数据的修改，只是查询，使用GET
     * 为了简化分页：只返回20条数据
     */
    @GET
    /**
     * 名字可以为任何字符，也可以为空
     */
    @Path("search/{name:(.*)?}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public ResponseModel<List<UserCard>> search(@DefaultValue("") @PathParam("name") String name) {
        User self = getSelf();
        // 先查询数据，查询的人封装为UserCard
        List<User> searchUsers = UserFactory.search(name);
        // 判断这些人是否有我已经关注的人
        // 如果有，则返回的状态中应该已经设置好了关注状态
        // 拿出我的联系人
        final List<User> contacts = UserFactory.contacts(self);
        // 把User转化为UserCard
        List<UserCard> userCards = searchUsers.stream()
                .map(user -> {
                    // 判断这个人是否是我自己或者在我的联系人当中
                    // 这里需要注意：判断是否在我的联系人当中，不能直接使用user去和我的联系人作比较
                    // 因为如果想通过user去判断，需要通过hashCode或者是equals，但是可能因为某些参数的不一致，导致有了这个联系人却返回false
                    boolean isFollow = user.getId().equalsIgnoreCase(self.getId())
                            // 进行联系人的任意匹配，匹配其中的id字段
                            || contacts.stream().anyMatch(
                                    contactUser -> contactUser.getId()
                                                    .equalsIgnoreCase(user.getId())
                    );

                    return new UserCard(user, isFollow);
                })
                .collect(Collectors.toList());

        return ResponseModel.buildOk(userCards);

    }


}
